use std::env;
use std::path::PathBuf;
use std::sync::{Arc, atomic::{AtomicBool, Ordering}};
use std::thread::sleep;
use std::time::Duration;

use chrono::Local;
use rusqlite::Connection;
use willhook::{keyboard_hook, KeyboardKey, KeyPress};

fn get_home_dir() -> Option<PathBuf> {
    if let Some(home_dir) = env::var_os("HOME") {
        // 在类Unix系统中，使用 "HOME" 环境变量获取家目录
        Some(PathBuf::from(home_dir))
    } else if let Some(profile_dir) = env::var_os("USERPROFILE") {
        // 在Windows系统中，使用 "USERPROFILE" 环境变量获取家目录
        Some(PathBuf::from(profile_dir))
    } else {
        // 在其他情况下，无法确定家目录路径
        None
    }
}

struct KeyStatistics {
    date: String,
    key: String,
    count: u64,
}

fn create_connection() -> Connection {
    let home_dir = get_home_dir().unwrap();
    let path = home_dir.join("key-statistics.db");
    let need_create_table = !path.exists();
    let connection = Connection::open(&path).unwrap();

    if need_create_table {
        println!("init db file: {}", &path.to_str().unwrap());
        connection.execute("create table key_statistics(date TEXT, key TEXT, count INTEGER); ", ()).unwrap();
    }

    connection
}

fn save_or_update(conn: &Connection, key: &str) {
        let date = Local::now().date_naive().to_string();
        let mut stmt = conn.prepare("select * from key_statistics where date = ?1 and key = ?2").unwrap();
        let mut key_iterators = stmt.query_map(&[&date, key], |row| {
            Ok(KeyStatistics {
                date: row.get(0)?,
                key: row.get(1)?,
                count: row.get(2)?,
            })
        }).unwrap();
        if let Some(key) = key_iterators.next() {
            let statistics = key.unwrap();
            conn.execute("update key_statistics set count = ?1 where date = ?2 and key = ?3", (&statistics.count + 1, &statistics.date, &statistics.key)).unwrap();
        } else {
            conn.execute("insert into key_statistics(date, key, count) values (?1, ?2, ?3)", (&date, key, 1)).unwrap();
        }
}

fn main() {
    let is_running = Arc::new(AtomicBool::new(true));
    let set_running = is_running.clone();

    let h = keyboard_hook().unwrap();
    let connection = create_connection();

    ctrlc::set_handler(move || {
        set_running.store(false, Ordering::SeqCst);
    })
        .expect("Error setting Ctrl-C handler");

    while is_running.load(Ordering::SeqCst) {
        sleep(Duration::from_millis(100));
        if let Ok(ie) = h.try_recv() {
            match ie {
                willhook::InputEvent::Keyboard(ke) => {
                    match ke.pressed {
                        KeyPress::Down(_) => {
                            let kbk = &ke.key.unwrap();
                            let key:&str = convert(kbk);
                            save_or_update(&connection, &key);
                        }
                        _ => {}
                    }
                }
                _ => (),
            }
        } else {
            std::thread::yield_now();
        }
    };
}

fn convert(kbk: &KeyboardKey) -> &str {
    match kbk {
        KeyboardKey::A => {"A"}
        KeyboardKey::B => {"B"}
        KeyboardKey::C => {"C"}
        KeyboardKey::D => {"D"}
        KeyboardKey::E => {"E"}
        KeyboardKey::F => {"F"}
        KeyboardKey::G => {"G"}
        KeyboardKey::H => {"H"}
        KeyboardKey::I => {"I"}
        KeyboardKey::J => {"J"}
        KeyboardKey::K => {"K"}
        KeyboardKey::L => {"L"}
        KeyboardKey::M => {"M"}
        KeyboardKey::N => {"N"}
        KeyboardKey::O => {"O"}
        KeyboardKey::P => {"P"}
        KeyboardKey::Q => {"Q"}
        KeyboardKey::R => {"R"}
        KeyboardKey::S => {"S"}
        KeyboardKey::T => {"T"}
        KeyboardKey::U => {"U"}
        KeyboardKey::V => {"V"}
        KeyboardKey::W => {"W"}
        KeyboardKey::X => {"X"}
        KeyboardKey::Y => {"Y"}
        KeyboardKey::Z => {"Z"}
        KeyboardKey::Number0 => {"Number0"}
        KeyboardKey::Number1 => {"Number1"}
        KeyboardKey::Number2 => {"Number2"}
        KeyboardKey::Number3 => {"Number3"}
        KeyboardKey::Number4 => {"Number4"}
        KeyboardKey::Number5 => {"Number5"}
        KeyboardKey::Number6 => {"Number6"}
        KeyboardKey::Number7 => {"Number7"}
        KeyboardKey::Number8 => {"Number8"}
        KeyboardKey::Number9 => {"Number9"}
        KeyboardKey::LeftAlt => {"LeftAlt"}
        KeyboardKey::RightAlt => {"RightAlt"}
        KeyboardKey::LeftShift => {"LeftShift"}
        KeyboardKey::RightShift => {"RightShift"}
        KeyboardKey::LeftControl => {"LeftControl"}
        KeyboardKey::RightControl => {"RightControl"}
        KeyboardKey::BackSpace => {"BackSpace"}
        KeyboardKey::Tab => {"Tab"}
        KeyboardKey::Enter => {"Enter"}
        KeyboardKey::Escape => {"Escape"}
        KeyboardKey::Space => {"Space"}
        KeyboardKey::PageUp => {"PageUp"}
        KeyboardKey::PageDown => {"PageDown"}
        KeyboardKey::Home => {"Home"}
        KeyboardKey::ArrowLeft => {"ArrowLeft"}
        KeyboardKey::ArrowUp => {"ArrowUp"}
        KeyboardKey::ArrowRight => {"ArrowRight"}
        KeyboardKey::ArrowDown => {"ArrowDown"}
        KeyboardKey::Print => {"Print"}
        KeyboardKey::PrintScreen => {"PrintScreen"}
        KeyboardKey::Insert => {"Insert"}
        KeyboardKey::Delete => {"Delete"}
        KeyboardKey::LeftWindows => {"LeftWindows"}
        KeyboardKey::RightWindows => {"RightWindows"}
        KeyboardKey::Comma => {"Comma"}
        KeyboardKey::Period => {"Period"}
        KeyboardKey::Slash => {"Slash"}
        KeyboardKey::SemiColon => {"SemiColon"}
        KeyboardKey::Apostrophe => {"Apostrophe"}
        KeyboardKey::LeftBrace => {"LeftBrace"}
        KeyboardKey::BackwardSlash => {"BackwardSlash"}
        KeyboardKey::RightBrace => {"RightBrace"}
        KeyboardKey::Grave => {"Grave"}
        KeyboardKey::F1 => {"F1"}
        KeyboardKey::F2 => {"F2"}
        KeyboardKey::F3 => {"F3"}
        KeyboardKey::F4 => {"F4"}
        KeyboardKey::F5 => {"F5"}
        KeyboardKey::F6 => {"F6"}
        KeyboardKey::F7 => {"F7"}
        KeyboardKey::F8 => {"F8"}
        KeyboardKey::F9 => {"F9"}
        KeyboardKey::F10 => {"F10"}
        KeyboardKey::F11 => {"F11"}
        KeyboardKey::F12 => {"F12"}
        KeyboardKey::F13 => {"F13"}
        KeyboardKey::F14 => {"F14"}
        KeyboardKey::F15 => {"F15"}
        KeyboardKey::F16 => {"F16"}
        KeyboardKey::F17 => {"F17"}
        KeyboardKey::F18 => {"F18"}
        KeyboardKey::F19 => {"F19"}
        KeyboardKey::F20 => {"F20"}
        KeyboardKey::F21 => {"F21"}
        KeyboardKey::F22 => {"F22"}
        KeyboardKey::F23 => {"F23"}
        KeyboardKey::F24 => {"F24"}
        KeyboardKey::NumLock => {"NumLock"}
        KeyboardKey::ScrollLock => {"ScrollLock"}
        KeyboardKey::CapsLock => {"CapsLock"}
        KeyboardKey::Numpad0 => {"Numpad0"}
        KeyboardKey::Numpad1 => {"Numpad1"}
        KeyboardKey::Numpad2 => {"Numpad2"}
        KeyboardKey::Numpad3 => {"Numpad3"}
        KeyboardKey::Numpad4 => {"Numpad4"}
        KeyboardKey::Numpad5 => {"Numpad5"}
        KeyboardKey::Numpad6 => {"Numpad6"}
        KeyboardKey::Numpad7 => {"Numpad7"}
        KeyboardKey::Numpad8 => {"Numpad8"}
        KeyboardKey::Numpad9 => {"Numpad9"}
        KeyboardKey::Multiply => {"Multiply"}
        KeyboardKey::Add => {"Add"}
        KeyboardKey::Separator => {"Separator"}
        KeyboardKey::Subtract => {"Subtract"}
        KeyboardKey::Decimal => {"Decimal"}
        KeyboardKey::Divide => {"Divide"}
        KeyboardKey::Other(_) => {"Other"}
        KeyboardKey::InvalidKeyCodeReceived => {"InvalidKeyCodeReceived"}
    }
}